//
//  LRJ_SampleCoreTextView.m
//  Pods
//
//  Created by imac_LRJ on 2022/6/7.
//

#import "LRJ_SampleCoreTextView.h"
#import "LRJ_TextureMakerAndResponder.h"
#import "LRJ_AttachmentProtocol.h"
#import "LRJ_ImgModel.h"
#import "LRJ_TextAttachment.h"
#import "LRJ_TextAttachment+bindAction.h"
#import "LRJ_TextureMakerAndResponder+touch.h"
#import "LRJ_MacroDefine.h"
#import "LRJ_ActiveRangeModel.h"
#import "LRJ_CTextLayoutFrame.h"
//定义key，用于userinfo的字典，然后取出来用于绘制，目的在于方便定制(一次性，而非多次，减少绘制次数)
//属性字符串key
NSString * const LRJ_AttributedItemKey  = @"LRJ_AttributedItemKey";
NSString * const LRJ_TextHorizontalAlignmentKey = @"LRJ_TextHorizontalAlignmentKey";
NSString * const LRJ_TextVerticalAlignmentKey = @"LRJ_TextVerticalAlignmentKey";

@interface LRJ_SampleCoreTextView()<LRJ_TextureMakerAndResponderDelegate,LRJ_TextureMakerAndResponderEventDelegate,LRJ_TextLayoutDelegate>
{
    //附件更新，比如图片等
    BOOL _pendingAttachmentUpdates;
}
@property (nonatomic, strong) NSRecursiveLock *lock;

//@property (nonatomic, strong) LRJ_TextureMakerAndResponder *textDrawer;

//附件数组，比如图片，自定义的view，等等
@property (nonatomic, strong) NSMutableArray <LRJ_TextAttachment *> *arrayAttachments;
@end



@implementation LRJ_SampleCoreTextView

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        _textDrawer = [[LRJ_TextureMakerAndResponder alloc] init];
        _textDrawer.delegate = self;
        _textDrawer.eventDelegate = self;
        _lock = [[NSRecursiveLock alloc] init];
        _arrayAttachments = [NSMutableArray array];
    }
    return self;
}
- (void)setFrame:(CGRect)frame
{
    if (!CGRectEqualToRect(frame, self.frame))
    {
        [super setFrame:frame];
        
        [self setNeedsDisplayAsync];
        
        _pendingAttachmentUpdates = YES;
    }
}

- (void)setHorizontalAlignment:(LRJ_TextHorizontalAlignment)horizontalAlignment
{
    if (_horizontalAlignment != horizontalAlignment) {
        _horizontalAlignment = horizontalAlignment;
        [self setNeedsDisplayAsync];
    }
}

- (void)setVerticalAlignment:(LRJ_TextVerticalAlignment)verticalAlignment
{
    if (_verticalAlignment != verticalAlignment) {
        _verticalAlignment = verticalAlignment;
        [self setNeedsDisplayAsync];
    }
}

- (void)setAttributedItem:(LRJ_MutableAttributedItem *)attributedItem
{
    if (_attributedItem != attributedItem)
    {
        _attributedItem = attributedItem;
        
        //异步的操作！！！
        [self setNeedsDisplayAsync];
        
        _pendingAttachmentUpdates = YES;
    }
}

- (void)setNumerOfLines:(NSUInteger)numerOfLines
{
    if (_textDrawer.textLayout.maximumNumberOfLines != numerOfLines) {
        _textDrawer.textLayout.maximumNumberOfLines = numerOfLines;
        _pendingAttachmentUpdates = YES;
        [self setNeedsDisplay];
    }
}

//返回当前的设置对象

- (NSDictionary *)currentDrawingUserInfo
{
    NSDictionary *dic = [super currentDrawingUserInfo];
    
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    
    if (dic) {
        [userInfo addEntriesFromDictionary:dic];
    }
    
    if (_attributedItem.resultString)
    {
        [userInfo setValue:_attributedItem.resultString forKey:LRJ_AttributedItemKey];
    }
    
    [userInfo setValue:@(_horizontalAlignment) forKey:LRJ_TextHorizontalAlignmentKey];
    [userInfo setValue:@(_verticalAlignment) forKey:LRJ_TextVerticalAlignmentKey];
    
    return userInfo;
}


#pragma mark --- override super ,绘制自己的内容

- (BOOL)drawInRect:(CGRect)rect withContext:(CGContextRef)context asynchronously:(BOOL)asynchronously userInfo:(NSDictionary *)userInfo
{
    [super drawInRect:rect withContext:context asynchronously:asynchronously userInfo:userInfo];
    
    NSUInteger initialDrawingCount = self.drawingCount;
    
    NSAttributedString *attributedString = userInfo[LRJ_AttributedItemKey];
    
    if (!attributedString) return YES;
    
    /**
     CTFramSetter CTFrame
     */
    //传入参数，textLayout.attributedString就是_attributedItem.resultString 富文本
    _textDrawer.frame = rect;
    _textDrawer.textLayout.attributedString = attributedString;
    
    //CTFrameRef
    LRJ_CTextLayoutFrame *layoutFrame = [_textDrawer.textLayout layoutFrame];
    CGSize layoutSize = [layoutFrame layoutSize];
    
    LRJ_TextHorizontalAlignment horizontalAlignment = [userInfo[LRJ_TextHorizontalAlignmentKey] unsignedIntegerValue];
    LRJ_TextVerticalAlignment verticalAlignment = [userInfo[LRJ_TextVerticalAlignmentKey] unsignedIntegerValue];
    
    if (horizontalAlignment == LRJ_TextHorizontalAlignmentRight) {
        CGPoint point = _textDrawer.drawOrigin;
        point.x = rect.size.width - layoutSize.width;
        _textDrawer.drawOrigin = point;
    }
    else if (horizontalAlignment == LRJ_TextHorizontalAlignmentCenter){
        CGPoint point = _textDrawer.drawOrigin;
        point.x = (rect.size.width - layoutSize.width) / 2;
        _textDrawer.drawOrigin = point;
    }
    
    if (verticalAlignment == LRJ_TextVerticalAlignmentBottom) {
        //坐标系翻转的
        CGPoint point = _textDrawer.drawOrigin;
        point.y = rect.size.height - layoutSize.height;
        _textDrawer.drawOrigin = point;
    }
    else if (verticalAlignment == LRJ_TextVerticalAlignmentCenter){
        CGPoint point = _textDrawer.drawOrigin;
        point.y = (rect.size.height - layoutSize.height) / 2;
        _textDrawer.drawOrigin = point;
    }
    else if (verticalAlignment == LRJ_TextVerticalAlignmentCenterCompatibility){
        CGFloat offset = 1;
        CGPoint point = _textDrawer.drawOrigin;
        point.y = (rect.size.height - layoutSize.height) / 2;
        point.y -= offset;
        _textDrawer.drawOrigin = point;
    }
    
    CGRect visibleRect = CGRectNull;
    //绘制关键方法
    [_textDrawer drawInContext:context visibleRect:visibleRect replaceAttachments:_pendingAttachmentUpdates shouldInterruptBlock:^BOOL{
        //重新绘制的时候，取消这一次的绘制
        if (initialDrawingCount != self.drawingCount)
        {
            NSLog(@"Interrupt happen！！！");
            return YES;
        }
        return NO;
    }];
    
    
    
    
    
    return YES;
}

- (void)drawingDidFinishAsynchronously:(BOOL)asynchronously success:(BOOL)success
{
    if (!success) {
        return;
    }
    
    [_lock lock];
    // 三个点： 锁重入、for循环遍历移除元素、多线程同步访问共享数据区
    for (__block int i = 0; i < _arrayAttachments.count; i++) {
        if (i >= 0) {
            LRJ_TextAttachment *att = [_arrayAttachments objectAtIndex:i];
            
            if (att.type == LRJ_AttachmentTypeStaticImage){
                LRJ_ImgModel *gImage = (LRJ_ImgModel *)att.contents;
                if ([gImage isKindOfClass:[LRJ_ImgModel class]]) {
                    [gImage wmg_loadImageWithUrl:gImage.downloadUrl options:0 progress:NULL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {

                        [self.lock lock];
                        if ([self.arrayAttachments containsObject:att]) {
                            [self.arrayAttachments removeObject:att];
                            i--;
                            [self setNeedsDisplay];
                        }
                        [self.lock unlock];
                    }];
                }
            }
        }
    }
    [_lock unlock];
}




- (BOOL)shouldDisableGestureRecognizerInLocation:(CGPoint)location
{
    for (LRJ_TextAttachment *att in _attributedItem.arrayAttachments) {
        if (att.type == LRJ_AttachmentTypeStaticImage && [att responseEvent]) {
            if (CGRectContainsPoint(att.layoutFrame, location)) {
                return YES;
            }
        }
    }

    return NO;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textDrawer touchesBegan:touches withEvent:event];

    if (!_textDrawer.pressingActiveRange)
    {
        [super touchesBegan:touches withEvent:event];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textDrawer touchesEnded:touches withEvent:event];
    [super touchesEnded:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textDrawer touchesMoved:touches withEvent:event];
     //如果没有正在响应，那就继承父类方法，看看需不需要展示点击状态
    if (!_textDrawer.pressingActiveRange)
    {
        [super touchesMoved:touches withEvent:event];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textDrawer touchesCancelled:touches withEvent:event];
    [super touchesCancelled:touches withEvent:event];
}

#pragma mark - LRJ_TextureMakerAndResponderDelegate

- (void)textDrawer:(LRJ_TextureMakerAndResponder *)LRJ_TextureMaker replaceAttachment:(LRJ_TextAttachment *)att frame:(CGRect)frame context:(CGContextRef)context
{
    if (att.type == LRJ_AttachmentTypeStaticImage)
    {
        if ([att.contents isKindOfClass:[NSString class]]) {
            UIGraphicsPushContext(context);
            UIImage *image = [UIImage imageNamed:(NSString *)att.contents];
            [image drawInRect:frame];
            UIGraphicsPopContext();
        }
        else if ([att.contents isKindOfClass:[UIImage class]]) {
            UIGraphicsPushContext(context);
            [(UIImage *)att.contents drawInRect:frame];
            UIGraphicsPopContext();
        }
        else if ([att.contents isKindOfClass:[LRJ_ImgModel class]]){
            LRJ_ImgModel *gImage = (LRJ_ImgModel *)att.contents;
            
            if (gImage.image) {
                UIGraphicsPushContext(context);
                [gImage.image drawInRect:frame];
                UIGraphicsPopContext();
            }
            else
            {
                if (!IsStrEmpty(gImage.placeholderName)) {
                    UIGraphicsPushContext(context);
                    UIImage *image = [UIImage imageNamed:gImage.placeholderName];
                    [image drawInRect:frame];
                    UIGraphicsPopContext();
                }
            }
            
            if (!IsStrEmpty(gImage.downloadUrl))
            {
                att.layoutFrame = frame;
                [_lock lock];
                [_arrayAttachments addObject:att];
                [_lock unlock];
            }
        }
    }
}
#pragma mark - LRJ_TextureMakerAndResponderEventDelegate

- (UIView *)contextViewForTextDrawer:(LRJ_TextureMakerAndResponder *)textDrawer
{
    return self;
}

- (NSArray *)activeRangesForTextDrawer:(LRJ_TextureMakerAndResponder *)textDrawer
{
    NSMutableArray *arrayActiveRanges = [NSMutableArray array];
    for (LRJ_TextAttachment *att in _attributedItem.arrayAttachments) {
        LRJ_ActiveRangeModel *range = [LRJ_ActiveRangeModel activeRange:NSMakeRange(att.position, att.length) type:LRJ_ActiveRangeTypeAttachment text:@""];
        range.bindingData = att;
        [arrayActiveRanges addObject:range];
    }

    if (self.textDrawer.textLayout.truncationStringLineRange.location != NSNotFound) {
        LRJ_ActiveRangeModel *range = [LRJ_ActiveRangeModel activeRange:NSMakeRange(self.textDrawer.textLayout.truncationStringLineRange.location, self.textDrawer.textLayout.truncationStringLineRange.length) type:LRJ_ActiveRangeTypeTrancate text:@""];
        range.bindingData = @"ddd";
        [arrayActiveRanges addObject:range];
    }
    
    
    return arrayActiveRanges;
}

- (void)textDrawer:(LRJ_TextureMakerAndResponder *)textDrawer didPressActiveRange:(id<LRJ_ActiveRangePtotocol>)activeRange
{
    if (activeRange.type == LRJ_ActiveRangeTypeAttachment) {
        LRJ_TextAttachment *att = (LRJ_TextAttachment *)activeRange.bindingData;
        [att handleEvent:att.contents];
    }
    if (activeRange.type == LRJ_ActiveRangeTypeTrancate) {
       //断行处理
        if (_trancatedBlock) {
            _trancatedBlock();
        }
//        [att handleEvent:self];

    }
}

- (BOOL)textDrawer:(LRJ_TextureMakerAndResponder *)textDrawer shouldInteractWithActiveRange:(id<LRJ_ActiveRangePtotocol>)activeRange
{
    return YES;
}

#pragma mark - WMGTextLayoutDelegate

- (CGFloat)textLayout:(LRJ_CTextLayout *)textLayout maximumWidthForTruncatedLine:(CTLineRef)lineRef atIndex:(NSUInteger)index
{
    return LRJ_TextLayoutMaximumWidth;
}
@end
